package com.zhk.entry.dao.impl;




import com.zhk.entry.annotation.Column;
import com.zhk.entry.annotation.Table;
import com.zhk.entry.dao.BaseDaoService;
import com.zhk.entry.util.ThreadConn;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 对数据库进行操作 <一句话功能简述> <功能详细描述>
 *
 * @author 姓名 工号
 * @version [版本号, 2019年5月20日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class BaseDao<T> implements BaseDaoService<T> {

    /**
     * 查询 <一句话功能简述> <功能详细描述>
     *
     * @param
     * @return
     * @see [类、类#方法、类#成员]
     */
    public List getQuery(T t, Connection con) {
//        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List queryList = null;
        try {
            con.setAutoCommit(false);
//            con = DbUtils.connectDB();
//            con = new ThreadConn().getConnection();
            String sql = getQuerySql(t);
            List list = getQueryList(t);
            ps = con.prepareStatement(sql);
            for (int i = 0; i < list.size(); i++) {
                ps.setObject(i + 1, list.get(i));
            }
            rs = ps.executeQuery();
            queryList = getresolving(rs, t.getClass());
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return queryList;
    }

    /**
     * 解析结果集
     *
     * @param rs
     * @param clasz
     * @return
     */
    private List getresolving(ResultSet rs, Class<? extends Object> clasz) {
        List list = new ArrayList();
        try {
            while (rs.next()) {
                Object obj = clasz.newInstance();
                Field[] fs = clasz.getDeclaredFields();
                for (int i = 0; i < fs.length; i++) {
                    Field f = fs[i];
                    f.setAccessible(true);
                    Column column = f.getAnnotation(Column.class);
                    Object value = null;
                    if (column != null) {
                        String columnName = column.columnName();
                        value = rs.getObject(columnName);
                    }

                    f.set(obj, value);
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    // 获取值
    public List getQueryList(T t) {
        Class clasz = t.getClass();
        Field[] fs = clasz.getDeclaredFields();
        List list = new ArrayList();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];

            f.setAccessible(true);
            try {
                Object value = f.get(t);
                Column column = f.getAnnotation(Column.class);

                if (value != null && column != null) {
                    list.add(value);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    /**
     * 对SQL进行拼接
     *
     * @param t
     * @return dawse
     */
    public String getQuerySql(T t) {
        Class clasz = t.getClass();
        StringBuffer sb = new StringBuffer("select * from");
        // 获取列表名
        String tableName = t.getClass().getAnnotation(Table.class).tableName();
        sb.append(" " + tableName).append(" where 1=1");

        Field[] fs = clasz.getDeclaredFields();

        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            try {
                f.setAccessible(true);
                Object value = f.get(t);
                Column column = f.getAnnotation(Column.class);
                if (value != null && column != null) {
                    String columnName = column.columnName();
                    sb.append(" and " + columnName + " =?");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return sb.toString();
    }

    /**
     * 修改订单 <一句话功能简述> <功能详细描述>
     *
     * @param
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int update(T t) {
        Connection con = null;
        PreparedStatement ps = null;
        Class clasz = t.getClass();

        try {
            con.setAutoCommit(false);
//            con = DbUtils.connectDB();
            con = new ThreadConn().getConnection();
            StringBuffer sb = new StringBuffer("update ");
            String tableName = t.getClass().getAnnotation(Table.class).tableName();
            // UPDATE emp SET empno = 1,ename = '李四';
            sb.append(" " + tableName).append(" set");

            Field[] fs = clasz.getDeclaredFields();
            List list = new ArrayList();
            String whereSql = "";
            Object primaryKey = null;
            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true);
                Object value = f.get(t);

                if (value != null) {

                    if (f.isAnnotationPresent(Column.class)) {
                        String columnLible = f.getAnnotation(Column.class).columnName();
                        if (f.getAnnotation(Column.class).isPrimaryKey()) {
                            whereSql = " where " + columnLible + " = ? ";
                            primaryKey = value;
                        } else {

                            sb.append(" " + columnLible).append(" = ?,");
                            list.add(value);
                        }

                    }
                }
            }
            list.add(primaryKey);
            sb = new StringBuffer(sb.toString().subSequence(0, sb.toString().length() - 1));
            sb.append(whereSql);
            ps = con.prepareStatement(sb.toString());
            for (int i = 0; i < list.size(); i++) {
                ps.setObject(i + 1, list.get(i));
            }

            int count = ps.executeUpdate();
            return count;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;

    }

    /**
     * 删除功能 <一句话功能简述> <功能详细描述>
     *
     * @param
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int delete(T t) {
        Connection con = null;
        PreparedStatement ps = null;

//        con = DbUtils.connectDB();
        con = new ThreadConn().getConnection();
        String columnName = t.getClass().getAnnotation(Table.class).tableName();
        // 拼接为 delete form 表名 where
        StringBuffer sb = new StringBuffer("delete from  ").append(columnName).append(" where");

        Class clasz = t.getClass();
        Field[] fs = clasz.getDeclaredFields();
        for (int i = 0; i < fs.length; i++) {
            Field f = fs[i];
            // 开权限
            // 得到当前对象的注解
            Column column = f.getAnnotation(Column.class);

            if (column != null && column.isPrimaryKey()) {
                f.setAccessible(true);
                Object obj;
                try {
                    obj = f.get(t);
                    sb.append(" " + column.columnName()).append(" = ").append(obj);
                    break;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
        System.out.println(sb.toString());
        try {
            ps = con.prepareStatement(sb.toString());
            return ps.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 添加功能 <一句话功能简述> <功能详细描述>
     *
     * @param
     * @return
     * @see [类、类#方法、类#成员]
     */
    public int save(T t, Connection con) {
//        Connection con = null;
        PreparedStatement ps = null;
        Class clasz = t.getClass();
        try {
//            con = DbUtils.connectDB();
//            con = new ThreadConn().getConnection();
            con.setAutoCommit(false);
            // insert into 表名 () values();
            StringBuffer sb = new StringBuffer("insert into ");
            String tableName = t.getClass().getAnnotation(Table.class).tableName();
            sb.append(tableName).append("(");

            Field[] fs = clasz.getDeclaredFields();
            List list = new ArrayList();

            for (int i = 0; i < fs.length; i++) {
                Field f = fs[i];
                f.setAccessible(true);
                Object value = f.get(t);

                if (value != null) {
                    if (f.isAnnotationPresent(Column.class)) {
                        String columnLatble = f.getAnnotation(Column.class).columnName();
                        sb.append(" " + columnLatble + ",");
                        list.add(value);
                    }
                }
            }
            sb = new StringBuffer(sb.toString().subSequence(0, sb.toString().length() - 1));
            sb.append(") values (");
            for (int i = 0; i < list.size(); i++) {
                sb.append(" ?,");
            }
            sb = new StringBuffer(sb.toString().subSequence(0, sb.toString().length() - 1));
            sb.append(")");
            ps = con.prepareStatement(sb.toString());
            for (int i = 0; i < list.size(); i++) {
                ps.setObject(i + 1, list.get(i));
            }

            return ps.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
